package com.fei.jvmtest;

import java.io.File;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.objectweb.asm.ClassReader;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.MethodNode;

import com.fei.jvmtest.method.BaseType;
import com.fei.jvmtest.method.MethodAccessFlags;

public class ReadJar {
	public static void main(String[] args) throws Exception {
		new ReadJar().read(new File("D:\\Project\\zy\\zy-common\\target\\zy-common-1.0.0.jar"));

		String s = "com.fei.Test";
		System.out.println(s.replace(".", "\\"));

	}

	private void read(File file) throws Exception {

		JarFile jarFile = new JarFile(file);
		
		Enumeration<JarEntry> enumFiles = jarFile.entries();
		String matchClassName = "TestBean";
		
		while (enumFiles.hasMoreElements()) {
			
			JarEntry jarEntry = enumFiles.nextElement();
			String name = jarEntry.getName();
			if (name.indexOf("META-INF") >= 0)
				continue;

			if (!name.endsWith("class")) {
				continue;
			}
			
			String className = name.substring(name.lastIndexOf("/") + 1, name.lastIndexOf("."));
			if(!className.equals(matchClassName)) continue;

			// 读取压缩文件中的某一个类的流
			InputStream inputStream = jarFile.getInputStream(jarEntry);
			
			// 调用check方法判断方法是否存在
			checkExistMethod(inputStream, "test");
		}

	}

	private boolean checkExistMethod(InputStream inputStream, String methodName) throws Exception {
		ClassReader cr = new ClassReader(inputStream);
		ClassNode cn = new ClassNode();
		cr.accept(cn, ClassReader.EXPAND_FRAMES);// 建议EXPAND_FRAMES
		// ASM树接口形式访问
		List<MethodNode> methods = cn.methods;
		
		for (int i = 0; i < methods.size(); ++i) {
			
			MethodNode method = methods.get(i);
			
			
			if (method.name.equals(methodName)) {
				System.out.println(method.name + ":" + MethodAccessFlags.getFormattedAccessFlags(method.access));
				System.out.println(method.desc);
				
				Type[] param = Type.getArgumentTypes(method.desc);
				for(Type t : param){
					System.out.println(t.getClassName());
				}
				return true;
			}

		}

		return false;
	}
	
	
	private List<String> readMethodDesc(String desc){
		List<String> params = new ArrayList<>();
		char[] data = desc.toCharArray();
		for(int i = 0 ; i < data.length;i++){
			if(data[i] != 'L'){
			}else{
			}
		}
		
		return params;
	}
}
